import hashlib
import json

from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.template import RequestContext, loader
from django.templatetags.static import static
from django.views.decorators.csrf import csrf_exempt

from accounts.models import User
from home.models import Image
from home.images import assignImage, isUserReviewer, assignReviewerImages, getTotalImageCount, getAllAssignedImageCount, getAssignedImageCount, getRemainImageCount, getUnassignedImages, getTaggedImageCount, withdrawImage

# Handlers of the Login(index.html) Page.
def indexView(request):
    """
    Display login page for the users.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponse
    @return: an object of HttpResponse which contains content of the login 
             page.
    """
    isLoggedOut = request.GET.get('logout')
    if ( isAllowAutoLogin(request) ):
        if ( isAdministratorAccount(request) ):
            return HttpResponseRedirect('/accounts/admin')
        else:
            return HttpResponseRedirect('/home/dashboard')

    template = loader.get_template('accounts/index.html')
    context = RequestContext(request, {
        'isLoggedOut': isLoggedOut
    })
    return HttpResponse(template.render(context))

def isAdministratorAccount(request):
    try:
        isAdministrator = request.session['isAdministrator']
        return isAdministrator
    except KeyError:
        return False
def isAllowAutoLogin(request):
    try:
        isAllowAutoLogin = request.session['isAllowAutoLogin']
        return isAllowAutoLogin
    except KeyError:
        return False

@csrf_exempt
def loginAction(request):
    """
    Handle login request for the users.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponse
    @return an object of HttpResponse which contains a JSON array which 
            contains the verify result.
    """
    username = request.POST.get('username', '')
    password = request.POST.get('password', '')
    isAllowAutoLogin = request.POST.get('isAllowAutoLogin', True)
    isAdministrator = checkAccess(username)

    result = {
        'isSuccessful': False,
        'isUsernameEmpty': not username,
        'isPassowrdEmpty': not password,
        'isAccountValid': False,
        'isAdministrator': isAdministrator,
    }
    if not result['isUsernameEmpty'] or not result['isPassowrdEmpty']:
        password = hashlib.md5(password).hexdigest()
        result['isAccountValid'] = isAccountValid(username, password)
        result['isSuccessful'] = result['isAccountValid']

        if result['isSuccessful']:
            createSession(request, username, isAllowAutoLogin, isAdministrator)

    return HttpResponse(json.dumps(result), content_type="application/json")

def isAccountValid(username, password):
    """
    Verify if the username and password of the user is valid.

    @type username: string
    @param username: the username of the user.
    @type password: string
    @param password: the password of the user(has encrypted using MD5).
    @rtype: boolean
    @return if the username and passowrd of the user is valid.
    """
    try:
        User.objects.get(
            Q(username=username),
            Q(password=password)
        )
        return True
    except:
        return False

def createSession(request, username, isAllowAutoLogin, isAdministrator):
    """
    Create sessions for the users who has logged in.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @type username: string
    @param username: the username of the user
    """
    request.session['isLoggedIn'] = True
    request.session['username'] = username
    request.session['isAllowAutoLogin'] = isAllowAutoLogin == 'true'
    request.session['isAdministrator'] = isAdministrator
    request.session['isReviewer'] = User.objects.get(username=username).isReviewer

@csrf_exempt
def logoutAction(request):
    """
    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponseRedirect
    @return an object of HttpResponseRedirect which will transfer the user
            to the login page.
    """
    try:
        del request.session['isLoggedIn']
        del request.session['isAllowAutoLogin']
        del request.session['isAdministrator']
        del request.session['isReviewer']
    except KeyError:
        pass

    return HttpResponseRedirect('/accounts?logout=true')

def checkAccess(username):
    try:
        isAdministrator = User.objects.get(username=username).isAdministrator
        return isAdministrator
    except:
        return False

def isUserLoggedIn(request):
    try:
        isLoggedIn = request.session['isLoggedIn']
        return isLoggedIn
    except KeyError:
        return False
        
def adminView(request):
    """
    Display admin page for the root.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponse
    @return: an object of HttpResponse which contains content of the login 
             page.
    """
    if ( isAllowAutoLogin(request) ):
        if not checkAccess(request.session['username']):
            return HttpResponseRedirect('/home/dashboard')
        else:
            template = loader.get_template('accounts/admin.html')
            context = RequestContext(request, {
            })
            return HttpResponse(template.render(context))

    elif isUserLoggedIn(request):
        template = loader.get_template('accounts/admin.html')
        context = RequestContext(request, {
            })
        return HttpResponse(template.render(context))
    else:
        return HttpResponseRedirect('/accounts')
    
    

@csrf_exempt
def presentAction(request):
    """
    Import created users.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponse
    @return an object of HttpResponse which contains a JSON array which 
            contains the verify result.
    """
    result = list()
    i = 0
    for x in User.objects.all():
        userInfo = {
        'username': x.username,
        'password': x.password,
        'isAdministrator': x.isAdministrator,
        'isReviewer': x.isReviewer
        }
        result.append(userInfo)
        i += 1
    return HttpResponse(json.dumps(result), content_type="application/json")

@csrf_exempt
def addUserAction(request):
    """
    Handle addUser request for the root.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponse
    @return an object of HttpResponse which contains a JSON array which 
            contains the verify result.
    """
    # username = request.POST.get('username', '')
    # password = request.POST.get('password', '')
    # isReviewer = True if (request.POST.get('isReviewer', '') == '1') else False
    post_data = json.loads(request.body)
    username = post_data['username']
    password = post_data['password']
    isReviewer = post_data['isReviewer']
    print isReviewer
    print username
    print password
    print type(isReviewer)

    result = {
        'isAccountValid': False,
    }

    password = hashlib.md5(password).hexdigest()
    result['isAccountValid'] = not isAccountValid(username, password)

    if result['isAccountValid']:
        user = User(username = username, password = password, isAdministrator=False, isReviewer=isReviewer)
        user.save()
            

    return HttpResponse(json.dumps(result), content_type="application/json")

@csrf_exempt
def removeUserAction(request):
    """
    Remove a user.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponse
    @return an object of HttpResponse which contains a JSON array which 
            contains the verify result.
    """
    # username = request.POST.get('username', '')
    # user = User.objects.get(username = username)
    post_data = json.loads(request.body)
    username = post_data['username']
    result = False;
    try:
        User.objects.get(username=username).delete()
        result = True;
    except:
        pass

    return HttpResponse(json.dumps(result), content_type="application/json")

@csrf_exempt
def saveAction(request):
    """
    Save the modification.

    @type request: HttpRequest
    @param request: an object of HttpRequest which contains information
                    of HTTP request.
    @rtype: HttpResponse
    @return an object of HttpResponse which contains a JSON array which 
            contains the verify result.
    """
    received_json = json.loads(request.body)
    username = received_json['username']
    newPassword = received_json['password']

    result = {
        'isChanged': False,
    }

    newPassword = hashlib.md5(newPassword).hexdigest()

    user = User.objects.get(username=username)
    user.password = newPassword
    user.save()
    result['isChanged'] = True

    return HttpResponse(json.dumps(result), content_type="application/json")

def isRangeValid(username, begin, end):
    """
    judge whether the range is valid
    """
    begin = int(begin)
    end = int(end)
    user = User.objects.get(username = username)

    try:
        if begin > end:
            return False
        elif begin < Image.objects.first().id:
            return False
        elif end > Image.objects.last().id:
            return False
        else:
            for x in range(begin, end + 1):
                number = Image.objects.get(id = x).tag_maker
                if number != None and number != user:
                    return False
    except:
        return False

    return True

def getPasswordAction(username):
    user = User.objects.get(username = username)
    password = user.password
    result = {
    'password': password
    }
    return result

@csrf_exempt
def assignImageAction(request):
    # username = request.POST.get('username', '')
    # imageCount = request.POST.get('imageCount', '')
    print request.body
    post_data = json.loads(request.body)
    username = post_data['username']
    imageCount = post_data['imageCount']
    try:
        imageCount = int(imageCount)
    except:
        result = {
        'isSuccessful': False,
        'errorMessage': 'Invalid Numver',
        }
        return HttpResponse(json.dumps(result), content_type="application/json")
    if isAdministratorAccount(request):
        result =  assignImage(username, imageCount)
    else:
        result = {
        'isSuccessful': False,
        'errorMessage': 'No access',
        }
    return HttpResponse(json.dumps(result), content_type="application/json")
    
@csrf_exempt
def assignReviewerImageAction(request):
    # username = request.POST.get('username', '')
    # imageCount = request.POST.get('imageCount', '')
    post_data = json.loads(request.body)
    username = post_data['username']
    imageCount = post_data['imageCount']
    try:
        imageCount = int(imageCount)
    except:
        result={
        'isSuccessful': False,
        'errorMessage': 'Invalid Number',
        }
        return HttpResponse(json.dumps(result), content_type="application/json")
    if isAdministratorAccount(request):
        result = assignReviewerImages(username, int(imageCount))
    else:
        result={
        'isSuccessful': False,
        'errorMessage': 'No access',
        }
    return HttpResponse(json.dumps(result), content_type="application/json")

@csrf_exempt
def getImageCountData(requst):
    totalImage = getTotalImageCount()
    assigned = getAllAssignedImageCount(False)
    result = {
        'total': totalImage,
        'assigned': assigned,
        'remain': totalImage - assigned,
    }
    return HttpResponse(json.dumps(result), content_type="application/json")

@csrf_exempt
def getUserImageCount(request):
    received_json = json.loads(request.body)
    username = received_json['username']
    # username = request.GET.get('username')
    total = getAssignedImageCount(username)
    tagged = getTaggedImageCount(username)
    remain = getRemainImageCount(username)
    result = {
        'total':total,
        'tagged': tagged,
        'remain': total -tagged
    }

    return HttpResponse(json.dumps(result), content_type="application/json")

@csrf_exempt
def withdrawUserImage(request):
    print request.body
    received_json = json.loads(request.body)
    print received_json
    username = received_json['username']
    count = received_json['count']
    result = {
        'isSuccessful': False
    }
    try:
        count = int(count)
    except:
        return HttpResponse(json.dumps(result), content_type="application/json")
    result['isSuccessful'] = withdrawImage(username, count)
    
    return HttpResponse(json.dumps(result), content_type="application/json")
